//1.接口超时，100s
//2.不需要写api前缀，比如http://LocaLhost：5000
//3.我们经常使用get和post，需要对着两个方法进行封装
//4.每次获取数据都要使用response.json（）才可以获取数据，需要封装
import { apiPrefix, HttpCode } from '@/config'
import { Message } from '@arco-design/web-vue'
//设置超时时间100s
const TIME_OUT = 100000
console.log(apiPrefix, TIME_OUT)

//2.基础的配置
const baseFetchOptions = {
  method: 'GET',
  mode: 'cors' as RequestMode,
  credentials: 'include' as RequestCredentials, // 允许发送 cookies
  headers: new Headers({
    'Content-Type': 'application/json',
  }),
  redirect: 'follow' as RequestRedirect,
}
//fetch参数类型
type FetchOptionType = Omit<RequestInit, 'body'> & {
  //todo  never 换 any
  params?: Record<string, never>
  body?: BodyInit | Record<string, never> | null
}
//2.封装基础的fetch请求

const baseFetch = <T>(url: string, fetchOptions: FetchOptionType): Promise<T> => {
  //将所有的配置信息合并起来
  const options: typeof baseFetchOptions & FetchOptionType = Object.assign(
    {},
    baseFetchOptions,
    fetchOptions,
  )
  //组装url
  let urlWithPrefix = `${apiPrefix}${url.startsWith('/') ? url : '/${url}'}`
  //结构出对应的请求方法，params,body参数
  const { method, params, body } = options
  //如果请求是GET方法，并且传递了params。将参数拼接到url/?params
  if (method === 'GET' && params) {
    const paramsArray: string[] = []
    Object.keys(params).forEach((key) => {
      paramsArray.push(`${key}=${encodeURIComponent(params[key])}`)
    })
    if (urlWithPrefix.search(/\?/) === -1) {
      urlWithPrefix += `?${paramsArray.join('&')}`
    } else {
      urlWithPrefix += `&${paramsArray.join('&')}`
    }
    delete options.params
  }
  if (body) {
    options.body = JSON.stringify(body)
  }

  // 添加 Authorization token（如果存在）
  const token = localStorage.getItem('token')
  if (token) {
    ;(options.headers as Headers).set('Authorization', `Bearer ${token}`)
  }

  return Promise.race([
    //使用定时器来检测是否超时
    new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('接口已超时')
      }, TIME_OUT)
    }),
    //发起一个正常的请求
    new Promise((resolve, reject) => {
      globalThis
        .fetch(urlWithPrefix, options as RequestInit)
        .then(async (res) => {
          const json = await res.json()
          // 检查 code 状态码
          if (json.code === HttpCode.success) {
            resolve(json)
          } else {
            Message.error(json.message)
            reject(new Error(json.message))
          }
          // if (!res.ok && !res.code === 'success') {
          //   const errorText = await res.text()
          //   reject(`HTTP 错误 ${res.status}: ${errorText}`)
          //   return
          // }
          // // 处理响应
          // const contentType = res.headers.get('content-type')
          // if (contentType && contentType.includes('application/json')) {
          //   resolve(res.json())
          // } else {
          //   resolve(res.text())
          // }
        })
        .catch((err) => {
          Message.error(err.message)
          reject(err)
          // // 更详细的错误信息
          // if (err.message === 'Failed to fetch') {
          //   reject('网络错误：无法连接到服务器，请检查网络或 CORS 配置')
          // } else {
          //   reject(err)
          // }
        })
    }),
  ]) as Promise<T>
}

export const request = <T>(url: string, options = {}) => {
  return baseFetch<T>(url, options)
}

export const get = <T>(url: string, options = {}) => {
  return request<T>(url, Object.assign({}, options, { method: 'GET' }))
}
export const post = <T>(url: string, options = {}) => {
  return request<T>(url, Object.assign({}, options, { method: 'POST' }))
}
